Skip to content

Ruby: Split callable and its body into two AST nodes.#21867

Open
aschackmull wants to merge 5 commits into
github:mainfrom
aschackmull:ruby/callable-body
Open

Ruby: Split callable and its body into two AST nodes.#21867
aschackmull wants to merge 5 commits into
github:mainfrom
aschackmull:ruby/callable-body

Conversation

@aschackmull
Copy link
Copy Markdown
Contributor

@aschackmull aschackmull commented May 19, 2026

The Ruby AST has been conflating callable AST nodes and their bodies, which make things awkward for CFG construction. This refactor separates the two and adds a getBody predicate to connect them.

@github-actions github-actions Bot added the Ruby label May 19, 2026
@aschackmull aschackmull force-pushed the ruby/callable-body branch 3 times, most recently from 263bb5c to 8098334 Compare May 22, 2026 07:19
@aschackmull aschackmull force-pushed the ruby/callable-body branch from 8098334 to 7dcd2d6 Compare May 22, 2026 09:06
@aschackmull aschackmull marked this pull request as ready for review May 22, 2026 12:07
@aschackmull aschackmull requested a review from a team as a code owner May 22, 2026 12:07
Copilot AI review requested due to automatic review settings May 22, 2026 12:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the Ruby AST model so callable nodes (methods, blocks, lambdas) no longer double as their statement-sequence bodies, instead introducing an explicit getBody() relationship to improve downstream CFG/dataflow construction.

Changes:

  • Introduce Callable.getBody() and update callable AST classes so bodies are represented as separate BodyStmt nodes.
  • Update Ruby control-flow and dataflow internals (and several framework/security libraries) to traverse callable bodies via getBody().
  • Regenerate/adjust Ruby library test .expected outputs to reflect the new AST shape (getBody: [StmtSequence] ... nodes).
Show a summary per file
File Description
ruby/ql/test/library-tests/modules/modules.expected Updates expected results for module/enclosing-module behavior due to callable body splitting.
ruby/ql/test/library-tests/modules/methods.expected Updates expected results for method-enclosing relationships due to callable body splitting.
ruby/ql/test/library-tests/ast/AstDesugar.expected Updates desugaring AST expectations to include explicit callable bodies.
ruby/ql/test/library-tests/ast/Ast.expected Updates core AST expectations to include explicit callable bodies.
ruby/ql/lib/codeql/ruby/security/InsecureDependencyQuery.qll Uses getBlock().getBody() to find URL parts in git_source blocks.
ruby/ql/lib/codeql/ruby/security/ImproperMemoizationQuery.qll Uses m.getBody() when inspecting the last statement of a method.
ruby/ql/lib/codeql/ruby/frameworks/XmlParsing.qll Traverses parser blocks through .getBlock().getBody() to find relevant calls.
ruby/ql/lib/codeql/ruby/frameworks/Slim.qll Uses .asCallableAstNode().getBody() as the template node source.
ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Routing.qll Route block wrappers now delegate statements via block.getBody().getAStmt().
ruby/ql/lib/codeql/ruby/experimental/Rbi.qll Updates RBI modeling to retrieve aliased type and sig-body calls via .getBody().
ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll Adjusts callable dataflow node hierarchy to avoid assuming a callable is a StmtSequenceNode.
ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll Updates implicit return handling to anchor on c.getBody().getAStmt().
ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll Updates ensure-splitting logic to use the updated BodyStmtTree API.
ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll Refactors CFG scope/tree logic to treat callables and their bodies as distinct nodes.
ruby/ql/lib/codeql/ruby/ast/Method.qll Introduces Callable.getBody() and updates callable subclasses accordingly.
ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll Adds synthesis support for synthetic callable bodies (BodyStmtKind).
ruby/ql/lib/codeql/ruby/ast/internal/Method.qll Updates internal callable representations (e.g., brace blocks) to expose getBody().
ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll Adds internal BodyStmt node classes and updates body-child extraction helpers.
ruby/ql/lib/codeql/ruby/ast/internal/AST.qll Extends cached AST wrappers/synth node kinds to include the new body node types.
ruby/ql/lib/codeql/ruby/ast/Expr.qll Updates BodyStmt.getStmt to allow synthesized children (supporting synthetic bodies).
ruby/ql/consistency-queries/CfgConsistency.ql Updates CFG consistency checks to account for BodyStmt no longer being conflated with callables.

Copilot's findings

  • Files reviewed: 21/21 changed files
  • Comments generated: 0

@aschackmull aschackmull added the no-change-note-required This PR does not need a change note label May 22, 2026
Copy link
Copy Markdown
Contributor

@hvitved hvitved left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice refactor!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-change-note-required This PR does not need a change note Ruby

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants